Пройшло 13 років з того часу як компанія SYNRC випустила була свій власний
брендований LDAP Directory Server на Erlang з підтримкою MongoDB. Взагалі
баз які підтримують префіксний і суфіксний пошук по B-Tree таблицям не так багато,
в основному це складні SQL та MongoDB. Хоча такі бази як Mnesia,
LMDB, BDB-похідні (RocksDB, LevelDB) немають повнотекстового пошуку,
це можна реалізувати шляхом повного траверса, що на цих базах зазвичай працює
швидко (якшо на С), і ше швидше якшо база підтримує mmap (LMDB).
Непереможний по перформенсу станом на зараз є OpenLDAP (LMDB),
однак нам хочеться мати свою імплементацію, яку можна було би використовувати
як фірмове сховище даних для директорії ресурсів підприємства згідно як
міжнародних стандартів так і стандартів України. Ми захотіли відмовитися
від зовнішньої бази даних (MongoDB) що ускладнює розробку, і хотілося вибрати
шось вбудовуване для Erlang, вибирали
між zambal/elmdb та
elixir-sqlite/exqlite,
переміг SQLite тому шо хотілося мати мінімальну ідіоматичну імплементацію,
така шоб з одного боку була зрозуміла навіть людям без глибокої освіти
в Computer Science, а з іншого боку відкривала двері в підтримку інших
промислових корпоративних SQL джерел даних (Oracle, T-SQL, PostgreSQL).
На відміну від попередньої версії SYNRC LDAP яка робилася під
стартап PEOPLE|SYNC який ми хотіли продати PEOPLE|NET, а потім Київстар,
як SyncML стартап по синхронізації контактних книг, ця версія
робиться для стартапа SYNRC CHAT який ми хочемо продати ГУР МО.
В цій версії ми значну увагу приділили сумісністю з клієнтами,
такими як Apache Directory Studio, а також усіма LDIF файлами
які ми змогли знайти в інтернеті.
Так як якісну безпечну розподілену інфраструктуру яка відповідає
міжнародним і українським стандартами неможливо створити без CA/CMS,
OCSP, TSP, LDAP, DNS/DNSSEC, MQTT серверів, то всі ці сервери є
фундаментом продуктів SYNRC які формують перший рівень фреймворку
Сохацького який умовно називається Security або Безпека Підприємства.
На цьому фреймворку побудовані головні
інфраструктурні елементи країни, а також реєстрові
системи.
Загалом, LDAP це дуже древня і надійна технологія яка присутня буквально у всіх топових компаніях,
корпораціях, великих і малих бізнесах. Так, є сучасній Identity Server продукти (Hashicorp)
які не підтримуються LDAP, але це поодинокі непопулярні маргінальні екземпляри. SYNRC LDAP
це гарний початок для малих, середніх і великих бізнесів навести порядок в штатних розкладах,
календарях, задачах, ресурсах підприємства, таких як автопарки, IoT, реєстрах персональних і промислових
комп'ютерів, портів, правил ABAC, правил маршрутизації, контактних книгах користувачів, одним словом
все для чого створений і де використовується LDAP.
Вертикальні бази
Я вперше познайомився з вертикальними базами коли працював в International Land Systems, Inc.
Тоді в нас була система документообігу на вертикальній базі, які дуже часто використовуються
в системах документообігу. Наприклад таку схему даних використовує Alfresco, а також
SQL розширення для зберігання XML у Oracle та інших SQL базах.
Основна ідея вертикальних баз, або схем, полягає в тому шо об'єкти зберігаються
не у плоских таблицях де кожен атрибут це окрема колонка, а всі атрибути та їх значення
зберігаються в трьох колонках, де перша — це номер об'єкта, друга — ім'я атрибута,
а третя — значення атрибуту. Це дозволяє тримати розріжені (атрибутами) об'єкти,
та певним чином спростити управління базою. Всі наївні імплементації вертикальних баз
страждаються по перформенсу, тому потрібно бути обрежним. Наприклад, ми не рекомендуємо
використовувати SYNRC LDAP де об'єм директоріє більше ніж пів мільйона співробітників,
наприклад для Walmart. Для великих корпорацій краще брати OpenLDAP.
Предметна область
Netscape, Sun DS, 389 DS, Oracle
PEOPLE|SYNC стартап SYNRC 2007 року підтримував також роботу з Sun Directory Server. Його родовід
бере початок від сервера OpenLDAP, в 1996 року стартував форк Netscape Directory Server.
Після банкротства Netscape право на код викупила компанія AOL, яка ліцензувала право на розробку
компанії Sun Microsystems, зберігши право на код. В 2009 році Sun DS був переіменований на 389 Directory Server,
а Oracle почала свій форк Sun DS під назвою
Oracle Directory Server.
389 Directory Server також можна зустріти під іменами Fedora DS та Red Hat DS, оскільки це основні
донори проекту.
Microsoft Active Directory
Традиційно кожна корпорація займається розробкою свого LDAP сервера,
компанія Microsoft випустила свій перший в 1999 році. Active Directory
у якості бекенда використовує Extensible Storage Engine ESENT.DLL,
також відомий як JetDB, на яцій побудований також Windows Registry,
Microsoft Access, та можливо і інші внутрішні продукти компанії Microsoft.
OpenLDAP, Apple Open Directory
Були часи, що OpenLDAP був вбудований в кожну версію Mac OS X,
але Apple почала розвивати свій власний
Open Directory Server,
оскільки безпека кожної корпорації полягає у тому числі в брендованих
LDAP серверах під свої потреби та політику розробки..
TCP сервер
Я неодноразово використовував написання LDAP серверу у своїх Erlang курсах,
а також на конференціях у якості майстер-класу по програмуванню, де ми
з аудиторією пишемо всі разом LDAP сервер за 45 хвилин з моїми коментарями
та інтеракцією. Рекорд на відео був поставлений 30 хвилин, так шо це не прікол,
я дійсню MVP всіх продуктів SYNRC можу написати за 30 хвилин кожен. Власне
це є одним з критеріїв SYNRC, що тісно переплетено з показником LOC.
Ця версія SYNRC LDAP з підтримкою SQLite займає 300 рядків коду і
проходить всі LDIF тест сюїти.
Перед початком поставте Erlang та його Erlang AST фронтенд Elixir.
Ставити можна завжди тільки Elixir, Erlang піде як залежність
в будь-якому пекедж менеджері.
Створюємо папку проекту і в ній створюємо файл mix.exs для уніфікованого
депенденсі і пекадж менеджера Erlang і Elixir мов, mix.
Крім класичної прелюдії mix.exs, нам цікавий параметр exqlite, це ім'я
бібліотеки пакетного менеджера hex.pm, яка містить в собі 8-мегабайтний Сі файл,
і FFI обгортку для нього яка в Erlang світі називається NIF.
Далі пишемо найпростіший ідіоматичний Erlang TCP сервер.
Довгий час я використовував класичні, розширені версії на недокументованій
функції prim_inet:async_accept, такий як 5HT/tcp,
але зрештою відмовився так як не вбачаю в надмірному контролі семантики процесу ніяких перевах,
для нас діє така сама семантика як в вебі, відвалився клієнт і нічого страшного,
нікому його контроль на рівні сигналінгу не потрібен. Ми не слідкуємо за LDAP клієнтами!
Якшо в config/config.exs немає параметра ldap:intance то створюється нова SQLite база
по рендомному хешу з налаштуваннями по перформансу: 1) відключений журнал,
2) ін-меморі буфер, 3) великий кеш, 4) примусова синхронність; які визначаються
відповідними SQL прагмами.
Архітектура TCP сервера відповідає POSIX, ми створюємо лістенер,
який на кожне вхідне TCP повідомлення стартує акцептори, які
стартують некотрольований Erlang процес — лупер,
який обслуговує вхідне TCP повідомлення. Для декодування використовується
згенерований ASN.1 компілятором енкодер/декодер LDAP протоколу
по файлу LDAP.ans1, який можна знайти прямо в RFC IETF на
нормативно-правових актах України.
Після геренації покладіть файли в LDAP.erl та LDAP.hrl в папку src проекту.
А в папці lib створіть обгортку для згенерованих рекордів за допомогою Record,
а також створіть козу Erlang аплікейшина в Elixir синтаксисі, файл ldap.ex:
Цей сервер вже може відповідати на запити ldapmodify але буде їх блокувати так як поки що
не відповідає належним чином. Запустити програму можна класичними мантрами Elixir, а
в Elixir Shell виконати функцію запуску TCP лістенера, для цього перевпевніться що
дефаултний порт 1389 вільний.
BIND
Для удачного демо я раджу починати з функції BIND. Для цього створимо в базі
записи по яким будемо аутентифікуватися.
ADD
DSE
Якшо тестувати наш прото-сервер не ldapmodify, а Apache Directory Studio,
то вона початково буде питати так званий Root DSE об'єкт запитуючи після
bind, search реквест з пустим DN. Для коректної репрезентації спеціалізованої
інформації ми прошиємо стандартну відповідь на цей запит для нашого
фірмового SYNRC LDAP сервера версії 2.0 який підтримує протокол LDAPv3.
Він підтримує SIMPLE спосіб аунтентифікації тільки (поки що) і два
іменних простори ключів: dc=synrc,dc=com ou=schema, як виманає декілька RFC.
Це всьо пакується у LDAPMessage і відправляється на клієнт функцією answer.
Після цього зможуть розгортати в інтерфейсі дерево об'єктів.
MODIFY
MODIFY DN
DELETE
SEARCH
COMPARE
ABANDON/UNBIND
Висновки
У цій статті ми переконалися, що можливо написати LDAP сервер на 300 рядків,
а також що SQLite підходить для малих підприємств у якості сховища даних.
Ми взяли повний контроль над продуктом, який не містить залежностей, що
функціонують за межами контексту віртуальної машини, а також
спростили процес розробки більш складних систем на базі цього продукту.
Продукт буде корисний для апробації в підприємства зі стандартизованими
та уніфікованими політиками управління ресурсами підприємствах,
в телекомунікаційних продуктах, комунікаторах, месенджерах, тощо.